package com.helloandroid.view

import android.content.Context
import android.util.AttributeSet
import android.view.ViewTreeObserver
import android.widget.RelativeLayout
import android.widget.TextView
import com.helloandroid.R
import com.helloandroid.tools.MyLog
import dai.android.util.AndroidUtils
import java.util.*


fun interface IMovingTextDataSource{
    fun newTextString():String
}

class MovingText @JvmOverloads constructor(
        ctx: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = 0
) : RelativeLayout(ctx, attrs, defStyle) {
    companion object {
        const val RIGHT_TO_LEFT = 1
        const val LEFT_TO_RIGHT = 2
    }

    //
    var readyRoll = false
    var firstLayoutListener: ViewTreeObserver.OnGlobalLayoutListener? = null

    val queue = LinkedList<TextView>()
    var timer: Timer? = null

    var task = object : TimerTask() {
        override fun run() {
            post {
                if (!readyRoll || dataSource == null) {
                    return@post
                }
                if (moveDir == RIGHT_TO_LEFT){
                    updateRightToLeft()
                }else{
                    updateLeftToRight()
                }
            }
        }
    }

    // default attrs
    val moveDir: Int
    val textMargin: Int
    val textColor: Int

    var dataSource:IMovingTextDataSource? = null

    init {
        // 解析下自定义属性
        val typedArray = ctx.obtainStyledAttributes(attrs, R.styleable.MovingText)
        moveDir = typedArray.getInt(R.styleable.MovingText_text_move_dir, RIGHT_TO_LEFT)
        textMargin = typedArray.getDimension(R.styleable.MovingText_text_margin, resources.getDimension(R.dimen.dp20)).toInt()
        textColor = typedArray.getColor(R.styleable.MovingText_text_color, resources.getColor(R.color.black, null))
        typedArray.recycle()

        firstLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
            readyRoll = true
            viewTreeObserver.removeOnGlobalLayoutListener(firstLayoutListener)
        }
        viewTreeObserver.addOnGlobalLayoutListener(firstLayoutListener)

        timer = Timer()
        timer!!.schedule(task, 0, 30L)
    }

    fun updateLeftToRight(){
        if (queue.isEmpty()){
            val tmpWidth = addOne(0f)
            queue.peek().x = (-tmpWidth).toFloat()
            return
        }

        queue.forEach { it ->
            it.x += 5
        }

        // 判断是否需要添加
        val lastTextView = queue.last
        if (lastTextView.x > 0f) {
            // 添加一个
            val tmpWidth = addOne(lastTextView.x)
            queue.last.x -= (tmpWidth + 2 * textMargin)
        }

        val firstTextView = queue.peek()
        if (firstTextView.x >= width) {
            removeView(firstTextView)
            queue.poll()
        }
    }

    fun updateRightToLeft(){
        if (queue.isEmpty()) {
            addOne(width.toFloat())
            return
        }

        queue.forEach { it ->
            it.x -= 5
        }
        // 判断是否需要添加
        val lastTextView = queue.last

        // 这里有个坑: lastTextView.width 第一次是0
        val lastViewRight = lastTextView.x + lastTextView.width
        if (lastViewRight < width && lastTextView.width > 0) {
            // 添加一个
            addOne(lastViewRight)
        }

        val firstTextView = queue.peek()
        val firstViewRight = firstTextView.x + firstTextView.width
        if (firstViewRight <= 0 && firstTextView.width > 0) {
            removeView(firstTextView)
            queue.poll()
        }
    }

    // 添加一个 TextView,并且返回textView的长度
    private fun addOne(startX: Float): Int {
        val textView = TextView(context)
        textView.text = dataSource!!.newTextString()
        textView.setTextColor(textColor)
        val tvSizePair = AndroidUtils.measureViewSize(textView)
        val marginParams = MarginLayoutParams(
                tvSizePair.first,
                tvSizePair.second)
        marginParams.setMargins(textMargin, 0, textMargin, 0)
        val lp = RelativeLayout.LayoutParams(marginParams)
        lp.addRule(RelativeLayout.CENTER_VERTICAL)
        textView.layoutParams = lp
        textView.x = startX
        addView(textView)
        queue.add(textView)
        return tvSizePair.first
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        timer?.cancel()
        timer = null
    }


}